// $ANTLR 3.2 Sep 23, 2009 12:02:23 D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g 2010-07-13 11:28:55

  package typechecker.ast;
  
  import typechecker.ast.type.*;
  import typechecker.ast.term.*;
  
  import java.util.LinkedList;
  import java.util.Stack;
  import java.util.Map;


import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;import java.util.Stack;
import java.util.List;
import java.util.ArrayList;

public class ASTBuilder extends TreeParser {
    public static final String[] tokenNames = new String[] {
        "<invalid>", "<EOR>", "<DOWN>", "<UP>", "SPATIU", "INDENT", "DEDENT", "FORALL", "ARROW", "TLAMBDA", "LAMBDA", "DOT", "SEMI", "EQ", "BIND", "OR", "DARROW", "STAR", "LETREC", "LET", "CASE", "OF", "IND", "COIND", "LPAREN", "RPAREN", "LCURLY", "RCURLY", "LANG", "RANG", "COLUMN", "ID", "TID", "WS", "COMMENT", "PROG", "PROLOG", "TERM", "TL_BINDING", "TL_BINDINGS", "LAM_ABS", "LAM_APP", "VAR", "TYPE_ABS", "TYPE_APP", "TVAR", "BRANCHES", "BRANCH", "FUNCTION", "FOR_ALL", "TCONS_APP", "DATATYPE", "TARGS", "TCONSTRUCTORS", "TCONS", "STARED_TYPE"
    };
    public static final int FUNCTION=48;
    public static final int TERM=37;
    public static final int STAR=17;
    public static final int STARED_TYPE=55;
    public static final int TCONS_APP=50;
    public static final int CASE=20;
    public static final int DEDENT=6;
    public static final int BRANCHES=46;
    public static final int ID=31;
    public static final int EOF=-1;
    public static final int LPAREN=24;
    public static final int INDENT=5;
    public static final int LAM_APP=41;
    public static final int RPAREN=25;
    public static final int PROG=35;
    public static final int IND=22;
    public static final int LETREC=18;
    public static final int RANG=29;
    public static final int BIND=14;
    public static final int LAM_ABS=40;
    public static final int COLUMN=30;
    public static final int TVAR=45;
    public static final int DARROW=16;
    public static final int TID=32;
    public static final int VAR=42;
    public static final int LAMBDA=10;
    public static final int EQ=13;
    public static final int TL_BINDING=38;
    public static final int COMMENT=34;
    public static final int DOT=11;
    public static final int SPATIU=4;
    public static final int TARGS=52;
    public static final int TCONSTRUCTORS=53;
    public static final int TYPE_ABS=43;
    public static final int FORALL=7;
    public static final int TL_BINDINGS=39;
    public static final int FOR_ALL=49;
    public static final int LCURLY=26;
    public static final int TYPE_APP=44;
    public static final int OF=21;
    public static final int SEMI=12;
    public static final int TLAMBDA=9;
    public static final int WS=33;
    public static final int OR=15;
    public static final int RCURLY=27;
    public static final int BRANCH=47;
    public static final int PROLOG=36;
    public static final int ARROW=8;
    public static final int DATATYPE=51;
    public static final int TCONS=54;
    public static final int COIND=23;
    public static final int LET=19;
    public static final int LANG=28;

    // delegates
    // delegators


        public ASTBuilder(TreeNodeStream input) {
            this(input, new RecognizerSharedState());
        }
        public ASTBuilder(TreeNodeStream input, RecognizerSharedState state) {
            super(input, state);
             
        }
        

    public String[] getTokenNames() { return ASTBuilder.tokenNames; }
    public String getGrammarFileName() { return "D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g"; }


      private Context<TermVariable> vars = new Context<TermVariable>();
      {
        vars.push(new TermVariable("unit")); 
        vars.push(new TermVariable("bind"));  
      }
      private Context<TypeVariable> tvars = new Context<TypeVariable>(){
        public TypeVariable lookup(String s){
          TypeVariable tc = super.lookup(s);
          if(tc instanceof TypeConstructor){
    			  /**
    			    * Type constructors can be identified by name. 
    			    * Every occurence has a different stage, so we must have different instances.
    			    */
            return new TypeConstructor(s);
          }
          return tc;
        }
      };
      public void p(Object o){
        System.out.println(o);
      }


    public static class prog_return extends TreeRuleReturnScope {
        public Expression exp;
        public List<InductiveDatatype> rdts;
    };

    // $ANTLR start "prog"
    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:44:1: prog returns [Expression exp, List<InductiveDatatype> rdts] : ^( PROG p= prolog[dts] ^( TL_BINDINGS ( tl_bind[lvars, types, exps] )* ) ^( TERM term ) ) ;
    public final ASTBuilder.prog_return prog() throws RecognitionException {
        ASTBuilder.prog_return retval = new ASTBuilder.prog_return();
        retval.start = input.LT(1);

        Expression term1 = null;



          List<TermVariable> lvars    = new LinkedList<TermVariable>();
          List<TypeExpression> types  = new LinkedList<TypeExpression>();
          List<Expression> exps       = new LinkedList<Expression>();  
          List<InductiveDatatype> dts = new LinkedList<InductiveDatatype>();

        try {
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:51:5: ( ^( PROG p= prolog[dts] ^( TL_BINDINGS ( tl_bind[lvars, types, exps] )* ) ^( TERM term ) ) )
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:51:7: ^( PROG p= prolog[dts] ^( TL_BINDINGS ( tl_bind[lvars, types, exps] )* ) ^( TERM term ) )
            {
            match(input,PROG,FOLLOW_PROG_in_prog70); 

            match(input, Token.DOWN, null); 
            pushFollow(FOLLOW_prolog_in_prog74);
            prolog(dts);

            state._fsp--;

            match(input,TL_BINDINGS,FOLLOW_TL_BINDINGS_in_prog78); 

            if ( input.LA(1)==Token.DOWN ) {
                match(input, Token.DOWN, null); 
                // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:51:42: ( tl_bind[lvars, types, exps] )*
                loop1:
                do {
                    int alt1=2;
                    int LA1_0 = input.LA(1);

                    if ( (LA1_0==TL_BINDING) ) {
                        alt1=1;
                    }


                    switch (alt1) {
                	case 1 :
                	    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:51:43: tl_bind[lvars, types, exps]
                	    {
                	    pushFollow(FOLLOW_tl_bind_in_prog81);
                	    tl_bind(lvars, types, exps);

                	    state._fsp--;


                	    }
                	    break;

                	default :
                	    break loop1;
                    }
                } while (true);


                match(input, Token.UP, null); 
            }
            match(input,TERM,FOLLOW_TERM_in_prog89); 

            match(input, Token.DOWN, null); 
            pushFollow(FOLLOW_term_in_prog91);
            term1=term();

            state._fsp--;


            match(input, Token.UP, null); 

            match(input, Token.UP, null); 
             
                    /* Desugaring of top-level bindings into lambda abstraction-application */
                    Expression texp = term1;
                    for(int i=lvars.size()-1; i >= 0; i--){
                      texp = new LambdaAbstraction(lvars.get(i), types.get(i), texp);
                      texp = new LambdaApplication(texp, exps.get(i));
                    }
                    retval.exp = texp;
                    retval.rdts = dts;
                    /* Clean up the top level bindings and data constructors */
                    vars.clear();
                    tvars.clear();
                  

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
        }
        return retval;
    }
    // $ANTLR end "prog"


    // $ANTLR start "tl_bind"
    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:67:1: tl_bind[List<TermVariable> lvars , List<TypeExpression> types, List<Expression> exps] : ^( TL_BINDING push_ID type term ) ;
    public final void tl_bind(List<TermVariable> lvars, List<TypeExpression> types, List<Expression> exps) throws RecognitionException {
        String push_ID2 = null;

        Expression term3 = null;

        TypeExpression type4 = null;


        try {
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:68:5: ( ^( TL_BINDING push_ID type term ) )
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:68:7: ^( TL_BINDING push_ID type term )
            {
            match(input,TL_BINDING,FOLLOW_TL_BINDING_in_tl_bind122); 

            match(input, Token.DOWN, null); 
            pushFollow(FOLLOW_push_ID_in_tl_bind124);
            push_ID2=push_ID();

            state._fsp--;

            pushFollow(FOLLOW_type_in_tl_bind126);
            type4=type();

            state._fsp--;

            pushFollow(FOLLOW_term_in_tl_bind128);
            term3=term();

            state._fsp--;


            match(input, Token.UP, null); 
             
                    lvars.add(vars.lookup(push_ID2)); 
                    exps.add(term3); 
                    types.add(type4); 
                  

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
        }
        return ;
    }
    // $ANTLR end "tl_bind"


    // $ANTLR start "prolog"
    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:77:1: prolog[List<InductiveDatatype> dts] : ^( PROLOG ( datatype[dts] )* ) ;
    public final void prolog(List<InductiveDatatype> dts) throws RecognitionException {
        try {
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:78:5: ( ^( PROLOG ( datatype[dts] )* ) )
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:78:7: ^( PROLOG ( datatype[dts] )* )
            {
            match(input,PROLOG,FOLLOW_PROLOG_in_prolog169); 

            if ( input.LA(1)==Token.DOWN ) {
                match(input, Token.DOWN, null); 
                // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:78:16: ( datatype[dts] )*
                loop2:
                do {
                    int alt2=2;
                    int LA2_0 = input.LA(1);

                    if ( (LA2_0==DATATYPE) ) {
                        alt2=1;
                    }


                    switch (alt2) {
                	case 1 :
                	    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:78:17: datatype[dts]
                	    {
                	    pushFollow(FOLLOW_datatype_in_prolog172);
                	    datatype(dts);

                	    state._fsp--;


                	    }
                	    break;

                	default :
                	    break loop2;
                    }
                } while (true);


                match(input, Token.UP, null); 
            }

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
        }
        return ;
    }
    // $ANTLR end "prolog"


    // $ANTLR start "datatype"
    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:80:1: datatype[List<InductiveDatatype> dts] : ^( DATATYPE name= push_CTID args[params] tconss[dt] ) ;
    public final void datatype(List<InductiveDatatype> dts) throws RecognitionException {
        String name = null;



          List<TypeVariable> params = new LinkedList<TypeVariable>();
          InductiveDatatype dt;

        try {
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:85:5: ( ^( DATATYPE name= push_CTID args[params] tconss[dt] ) )
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:85:7: ^( DATATYPE name= push_CTID args[params] tconss[dt] )
            {
            match(input,DATATYPE,FOLLOW_DATATYPE_in_datatype204); 

            match(input, Token.DOWN, null); 
            pushFollow(FOLLOW_push_CTID_in_datatype209);
            name=push_CTID();

            state._fsp--;

            pushFollow(FOLLOW_args_in_datatype230);
            args(params);

            state._fsp--;

             dt = new InductiveDatatype(new TypeConstructor(name), params); 
            pushFollow(FOLLOW_tconss_in_datatype250);
            tconss(dt);

            state._fsp--;


            match(input, Token.UP, null); 
             
            			 /* Add type parameters as parameters to constructors */
            			 for( int i=0; i < params.size(); i++){
            			   TypeVariable v = tvars.pop(); 
            			   for( Map.Entry<DataConstructor, TypeExpression> kv : dt.entrySet()){
            			     TypeExpression crt = kv.getValue();
            			     kv.setValue(new ForallType(v, crt));
            			   }
            			 }
                   dts.add(dt); 
            			

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
        }
        return ;
    }
    // $ANTLR end "datatype"


    // $ANTLR start "args"
    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:101:1: args[ List<TypeVariable> params ] : ^( TARGS (arg= push_TID )* ) ;
    public final void args(List<TypeVariable> params) throws RecognitionException {
        String arg = null;


        try {
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:102:5: ( ^( TARGS (arg= push_TID )* ) )
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:102:7: ^( TARGS (arg= push_TID )* )
            {
            match(input,TARGS,FOLLOW_TARGS_in_args284); 

            if ( input.LA(1)==Token.DOWN ) {
                match(input, Token.DOWN, null); 
                // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:102:15: (arg= push_TID )*
                loop3:
                do {
                    int alt3=2;
                    int LA3_0 = input.LA(1);

                    if ( (LA3_0==TID) ) {
                        alt3=1;
                    }


                    switch (alt3) {
                	case 1 :
                	    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:102:16: arg= push_TID
                	    {
                	    pushFollow(FOLLOW_push_TID_in_args289);
                	    arg=push_TID();

                	    state._fsp--;

                	     params.add(tvars.lookup(arg));

                	    }
                	    break;

                	default :
                	    break loop3;
                    }
                } while (true);


                match(input, Token.UP, null); 
            }

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
        }
        return ;
    }
    // $ANTLR end "args"


    // $ANTLR start "tconss"
    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:103:1: tconss[InductiveDatatype dt] : ^( TCONSTRUCTORS ( tcons[dt] )* ) ;
    public final void tconss(InductiveDatatype dt) throws RecognitionException {
        try {
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:104:5: ( ^( TCONSTRUCTORS ( tcons[dt] )* ) )
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:104:7: ^( TCONSTRUCTORS ( tcons[dt] )* )
            {
            match(input,TCONSTRUCTORS,FOLLOW_TCONSTRUCTORS_in_tconss314); 

            if ( input.LA(1)==Token.DOWN ) {
                match(input, Token.DOWN, null); 
                // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:104:23: ( tcons[dt] )*
                loop4:
                do {
                    int alt4=2;
                    int LA4_0 = input.LA(1);

                    if ( (LA4_0==TCONS) ) {
                        alt4=1;
                    }


                    switch (alt4) {
                	case 1 :
                	    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:104:25: tcons[dt]
                	    {
                	    pushFollow(FOLLOW_tcons_in_tconss318);
                	    tcons(dt);

                	    state._fsp--;


                	    }
                	    break;

                	default :
                	    break loop4;
                    }
                } while (true);


                match(input, Token.UP, null); 
            }

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
        }
        return ;
    }
    // $ANTLR end "tconss"


    // $ANTLR start "tcons"
    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:105:1: tcons[InductiveDatatype dt] : ^( TCONS push_CID type ) ;
    public final void tcons(InductiveDatatype dt) throws RecognitionException {
        String push_CID5 = null;

        TypeExpression type6 = null;


        try {
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:106:5: ( ^( TCONS push_CID type ) )
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:106:7: ^( TCONS push_CID type )
            {
            match(input,TCONS,FOLLOW_TCONS_in_tcons337); 

            match(input, Token.DOWN, null); 
            pushFollow(FOLLOW_push_CID_in_tcons339);
            push_CID5=push_CID();

            state._fsp--;

            pushFollow(FOLLOW_type_in_tcons341);
            type6=type();

            state._fsp--;


            match(input, Token.UP, null); 
             dt.put((DataConstructor)vars.lookup(push_CID5), type6);

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
        }
        return ;
    }
    // $ANTLR end "tcons"


    // $ANTLR start "term"
    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:109:1: term returns [Expression exp] : ( ^( CASE ty= type t= term branches[((CaseAnalisys)$exp)] ) | ^( LETREC type push_ID t= term ) | ^( TYPE_ABS push_TID t= term ) | ^( TYPE_APP t= term ty= type ) | ^( LAM_ABS push_ID ty= type b= term ) | ^( LAM_APP t1= term t2= term ) | ^( VAR ID ) );
    public final Expression term() throws RecognitionException {
        Expression exp = null;

        CommonTree ID11=null;
        TypeExpression ty = null;

        Expression t = null;

        Expression b = null;

        Expression t1 = null;

        Expression t2 = null;

        TypeExpression type7 = null;

        String push_ID8 = null;

        String push_TID9 = null;

        String push_ID10 = null;


        try {
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:110:5: ( ^( CASE ty= type t= term branches[((CaseAnalisys)$exp)] ) | ^( LETREC type push_ID t= term ) | ^( TYPE_ABS push_TID t= term ) | ^( TYPE_APP t= term ty= type ) | ^( LAM_ABS push_ID ty= type b= term ) | ^( LAM_APP t1= term t2= term ) | ^( VAR ID ) )
            int alt5=7;
            switch ( input.LA(1) ) {
            case CASE:
                {
                alt5=1;
                }
                break;
            case LETREC:
                {
                alt5=2;
                }
                break;
            case TYPE_ABS:
                {
                alt5=3;
                }
                break;
            case TYPE_APP:
                {
                alt5=4;
                }
                break;
            case LAM_ABS:
                {
                alt5=5;
                }
                break;
            case LAM_APP:
                {
                alt5=6;
                }
                break;
            case VAR:
                {
                alt5=7;
                }
                break;
            default:
                NoViableAltException nvae =
                    new NoViableAltException("", 5, 0, input);

                throw nvae;
            }

            switch (alt5) {
                case 1 :
                    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:110:7: ^( CASE ty= type t= term branches[((CaseAnalisys)$exp)] )
                    {
                    match(input,CASE,FOLLOW_CASE_in_term365); 

                    match(input, Token.DOWN, null); 
                    pushFollow(FOLLOW_type_in_term369);
                    ty=type();

                    state._fsp--;

                    pushFollow(FOLLOW_term_in_term373);
                    t=term();

                    state._fsp--;

                     exp = new CaseAnalisys(t,ty); 
                    pushFollow(FOLLOW_branches_in_term377);
                    branches(((CaseAnalisys)exp));

                    state._fsp--;


                    match(input, Token.UP, null); 

                    }
                    break;
                case 2 :
                    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:111:7: ^( LETREC type push_ID t= term )
                    {
                    match(input,LETREC,FOLLOW_LETREC_in_term393); 

                    match(input, Token.DOWN, null); 
                    pushFollow(FOLLOW_type_in_term395);
                    type7=type();

                    state._fsp--;

                    pushFollow(FOLLOW_push_ID_in_term397);
                    push_ID8=push_ID();

                    state._fsp--;

                    pushFollow(FOLLOW_term_in_term401);
                    t=term();

                    state._fsp--;


                    match(input, Token.UP, null); 
                     exp = new Letrec(type7, vars.lookup(push_ID8), t); vars.pop(); 

                    }
                    break;
                case 3 :
                    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:113:7: ^( TYPE_ABS push_TID t= term )
                    {
                    match(input,TYPE_ABS,FOLLOW_TYPE_ABS_in_term427); 

                    match(input, Token.DOWN, null); 
                    pushFollow(FOLLOW_push_TID_in_term429);
                    push_TID9=push_TID();

                    state._fsp--;

                    pushFollow(FOLLOW_term_in_term433);
                    t=term();

                    state._fsp--;


                    match(input, Token.UP, null); 
                     exp = new TypeAbstraction(tvars.lookup(push_TID9),t ); tvars.pop(); 

                    }
                    break;
                case 4 :
                    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:115:7: ^( TYPE_APP t= term ty= type )
                    {
                    match(input,TYPE_APP,FOLLOW_TYPE_APP_in_term461); 

                    match(input, Token.DOWN, null); 
                    pushFollow(FOLLOW_term_in_term465);
                    t=term();

                    state._fsp--;

                    pushFollow(FOLLOW_type_in_term469);
                    ty=type();

                    state._fsp--;


                    match(input, Token.UP, null); 
                     exp = new TypeApplication(t, ty); 

                    }
                    break;
                case 5 :
                    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:117:7: ^( LAM_ABS push_ID ty= type b= term )
                    {
                    match(input,LAM_ABS,FOLLOW_LAM_ABS_in_term493); 

                    match(input, Token.DOWN, null); 
                    pushFollow(FOLLOW_push_ID_in_term495);
                    push_ID10=push_ID();

                    state._fsp--;

                    pushFollow(FOLLOW_type_in_term499);
                    ty=type();

                    state._fsp--;

                    pushFollow(FOLLOW_term_in_term503);
                    b=term();

                    state._fsp--;


                    match(input, Token.UP, null); 
                     exp = new LambdaAbstraction(vars.lookup(push_ID10), ty, b); vars.pop(); 

                    }
                    break;
                case 6 :
                    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:119:7: ^( LAM_APP t1= term t2= term )
                    {
                    match(input,LAM_APP,FOLLOW_LAM_APP_in_term525); 

                    match(input, Token.DOWN, null); 
                    pushFollow(FOLLOW_term_in_term529);
                    t1=term();

                    state._fsp--;

                    pushFollow(FOLLOW_term_in_term533);
                    t2=term();

                    state._fsp--;


                    match(input, Token.UP, null); 
                     exp = new LambdaApplication(t1, t2); 

                    }
                    break;
                case 7 :
                    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:121:7: ^( VAR ID )
                    {
                    match(input,VAR,FOLLOW_VAR_in_term559); 

                    match(input, Token.DOWN, null); 
                    ID11=(CommonTree)match(input,ID,FOLLOW_ID_in_term561); 

                    match(input, Token.UP, null); 
                     exp = vars.lookup((ID11!=null?ID11.getText():null)); 

                    }
                    break;

            }
        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
        }
        return exp;
    }
    // $ANTLR end "term"


    // $ANTLR start "branches"
    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:125:1: branches[CaseAnalisys ca ] : ^( BRANCHES ( branch[ca] )* ) ;
    public final void branches(CaseAnalisys ca) throws RecognitionException {
        try {
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:125:29: ( ^( BRANCHES ( branch[ca] )* ) )
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:125:31: ^( BRANCHES ( branch[ca] )* )
            {
            match(input,BRANCHES,FOLLOW_BRANCHES_in_branches609); 

            if ( input.LA(1)==Token.DOWN ) {
                match(input, Token.DOWN, null); 
                // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:125:42: ( branch[ca] )*
                loop6:
                do {
                    int alt6=2;
                    int LA6_0 = input.LA(1);

                    if ( (LA6_0==BRANCH) ) {
                        alt6=1;
                    }


                    switch (alt6) {
                	case 1 :
                	    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:125:42: branch[ca]
                	    {
                	    pushFollow(FOLLOW_branch_in_branches611);
                	    branch(ca);

                	    state._fsp--;


                	    }
                	    break;

                	default :
                	    break loop6;
                    }
                } while (true);


                match(input, Token.UP, null); 
            }

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
        }
        return ;
    }
    // $ANTLR end "branches"


    // $ANTLR start "branch"
    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:126:1: branch[CaseAnalisys ca ] : ^( BRANCH ID t= term ) ;
    public final void branch(CaseAnalisys ca) throws RecognitionException {
        CommonTree ID12=null;
        Expression t = null;


        try {
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:127:5: ( ^( BRANCH ID t= term ) )
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:127:7: ^( BRANCH ID t= term )
            {
            match(input,BRANCH,FOLLOW_BRANCH_in_branch632); 

            match(input, Token.DOWN, null); 
            ID12=(CommonTree)match(input,ID,FOLLOW_ID_in_branch634); 
            pushFollow(FOLLOW_term_in_branch638);
            t=term();

            state._fsp--;


            match(input, Token.UP, null); 
             ca.put(vars.lookup((ID12!=null?ID12.getText():null)), t); 

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
        }
        return ;
    }
    // $ANTLR end "branch"


    // $ANTLR start "type"
    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:132:1: type returns [TypeExpression texp ] : ( ^( ARROW t1= type t2= type ) | ^( FOR_ALL push_TID t= type ) | ^( TVAR TID ) | ^( TVAR ^( STARED_TYPE TID ) ) | tc= tcons_app );
    public final TypeExpression type() throws RecognitionException {
        TypeExpression texp = null;

        CommonTree TID14=null;
        CommonTree TID15=null;
        TypeExpression t1 = null;

        TypeExpression t2 = null;

        TypeExpression t = null;

        TypeExpression tc = null;

        String push_TID13 = null;


        try {
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:133:5: ( ^( ARROW t1= type t2= type ) | ^( FOR_ALL push_TID t= type ) | ^( TVAR TID ) | ^( TVAR ^( STARED_TYPE TID ) ) | tc= tcons_app )
            int alt7=5;
            switch ( input.LA(1) ) {
            case ARROW:
                {
                alt7=1;
                }
                break;
            case FOR_ALL:
                {
                alt7=2;
                }
                break;
            case TVAR:
                {
                int LA7_3 = input.LA(2);

                if ( (LA7_3==DOWN) ) {
                    int LA7_5 = input.LA(3);

                    if ( (LA7_5==TID) ) {
                        alt7=3;
                    }
                    else if ( (LA7_5==STARED_TYPE) ) {
                        alt7=4;
                    }
                    else {
                        NoViableAltException nvae =
                            new NoViableAltException("", 7, 5, input);

                        throw nvae;
                    }
                }
                else {
                    NoViableAltException nvae =
                        new NoViableAltException("", 7, 3, input);

                    throw nvae;
                }
                }
                break;
            case TCONS_APP:
                {
                alt7=5;
                }
                break;
            default:
                NoViableAltException nvae =
                    new NoViableAltException("", 7, 0, input);

                throw nvae;
            }

            switch (alt7) {
                case 1 :
                    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:133:7: ^( ARROW t1= type t2= type )
                    {
                    match(input,ARROW,FOLLOW_ARROW_in_type672); 

                    match(input, Token.DOWN, null); 
                    pushFollow(FOLLOW_type_in_type676);
                    t1=type();

                    state._fsp--;

                    pushFollow(FOLLOW_type_in_type680);
                    t2=type();

                    state._fsp--;


                    match(input, Token.UP, null); 
                     texp = new FunctionType(t1, t2); 

                    }
                    break;
                case 2 :
                    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:135:7: ^( FOR_ALL push_TID t= type )
                    {
                    match(input,FOR_ALL,FOLLOW_FOR_ALL_in_type704); 

                    match(input, Token.DOWN, null); 
                    pushFollow(FOLLOW_push_TID_in_type706);
                    push_TID13=push_TID();

                    state._fsp--;

                    pushFollow(FOLLOW_type_in_type710);
                    t=type();

                    state._fsp--;


                    match(input, Token.UP, null); 
                     texp = new ForallType(tvars.lookup(push_TID13), t); tvars.pop(); 

                    }
                    break;
                case 3 :
                    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:137:7: ^( TVAR TID )
                    {
                    match(input,TVAR,FOLLOW_TVAR_in_type738); 

                    match(input, Token.DOWN, null); 
                    TID14=(CommonTree)match(input,TID,FOLLOW_TID_in_type740); 

                    match(input, Token.UP, null); 
                     texp = tvars.lookup((TID14!=null?TID14.getText():null)); 

                    }
                    break;
                case 4 :
                    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:139:7: ^( TVAR ^( STARED_TYPE TID ) )
                    {
                    match(input,TVAR,FOLLOW_TVAR_in_type777); 

                    match(input, Token.DOWN, null); 
                    match(input,STARED_TYPE,FOLLOW_STARED_TYPE_in_type780); 

                    match(input, Token.DOWN, null); 
                    TID15=(CommonTree)match(input,TID,FOLLOW_TID_in_type782); 

                    match(input, Token.UP, null); 

                    match(input, Token.UP, null); 
                     TypeConstructor tt = (TypeConstructor) tvars.lookup((TID15!=null?TID15.getText():null)); tt.setStarred(); texp = tt; 

                    }
                    break;
                case 5 :
                    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:141:7: tc= tcons_app
                    {
                    pushFollow(FOLLOW_tcons_app_in_type806);
                    tc=tcons_app();

                    state._fsp--;

                     texp = tc; 

                    }
                    break;

            }
        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
        }
        return texp;
    }
    // $ANTLR end "type"


    // $ANTLR start "tcons_app"
    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:146:1: tcons_app returns [TypeExpression texp ] : ^( TCONS_APP ty= type (t= type )* ) ;
    public final TypeExpression tcons_app() throws RecognitionException {
        TypeExpression texp = null;

        TypeExpression ty = null;

        TypeExpression t = null;



          List<TypeExpression> params = new LinkedList<TypeExpression>();

        try {
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:154:5: ( ^( TCONS_APP ty= type (t= type )* ) )
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:154:7: ^( TCONS_APP ty= type (t= type )* )
            {
            match(input,TCONS_APP,FOLLOW_TCONS_APP_in_tcons_app860); 

            match(input, Token.DOWN, null); 
            pushFollow(FOLLOW_type_in_tcons_app864);
            ty=type();

            state._fsp--;

            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:154:27: (t= type )*
            loop8:
            do {
                int alt8=2;
                int LA8_0 = input.LA(1);

                if ( (LA8_0==ARROW||LA8_0==TVAR||(LA8_0>=FOR_ALL && LA8_0<=TCONS_APP)) ) {
                    alt8=1;
                }


                switch (alt8) {
            	case 1 :
            	    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:154:28: t= type
            	    {
            	    pushFollow(FOLLOW_type_in_tcons_app869);
            	    t=type();

            	    state._fsp--;

            	    params.add(t);

            	    }
            	    break;

            	default :
            	    break loop8;
                }
            } while (true);


            match(input, Token.UP, null); 
             texp = new TypeConstructorApplication((TypeConstructor) ty, params); 

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
        }
        return texp;
    }
    // $ANTLR end "tcons_app"


    // $ANTLR start "push_ID"
    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:159:1: push_ID returns [String text] : ID ;
    public final String push_ID() throws RecognitionException {
        String text = null;

        CommonTree ID16=null;

        try {
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:159:34: ( ID )
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:159:36: ID
            {
            ID16=(CommonTree)match(input,ID,FOLLOW_ID_in_push_ID924); 
             vars.push(new TermVariable((ID16!=null?ID16.getText():null)));  text =(ID16!=null?ID16.getText():null); 

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
        }
        return text;
    }
    // $ANTLR end "push_ID"


    // $ANTLR start "push_CID"
    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:160:1: push_CID returns [String text] : ID ;
    public final String push_CID() throws RecognitionException {
        String text = null;

        CommonTree ID17=null;

        try {
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:160:34: ( ID )
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:160:36: ID
            {
            ID17=(CommonTree)match(input,ID,FOLLOW_ID_in_push_CID940); 
             vars.push((TermVariable)new DataConstructor((ID17!=null?ID17.getText():null)));  text =(ID17!=null?ID17.getText():null); 

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
        }
        return text;
    }
    // $ANTLR end "push_CID"


    // $ANTLR start "push_TID"
    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:161:1: push_TID returns [String text] : TID ;
    public final String push_TID() throws RecognitionException {
        String text = null;

        CommonTree TID18=null;

        try {
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:161:34: ( TID )
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:161:36: TID
            {
            TID18=(CommonTree)match(input,TID,FOLLOW_TID_in_push_TID956); 
            tvars.push(new TypeVariable((TID18!=null?TID18.getText():null))); text =(TID18!=null?TID18.getText():null);

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
        }
        return text;
    }
    // $ANTLR end "push_TID"


    // $ANTLR start "push_CTID"
    // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:162:1: push_CTID returns [String text] : TID ;
    public final String push_CTID() throws RecognitionException {
        String text = null;

        CommonTree TID19=null;

        try {
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:162:34: ( TID )
            // D:\\workspace\\TBT-front-end\\grammar\\ASTBuilder.g:162:36: TID
            {
            TID19=(CommonTree)match(input,TID,FOLLOW_TID_in_push_CTID971); 
            tvars.push((TypeVariable)new TypeConstructor((TID19!=null?TID19.getText():null))); text =(TID19!=null?TID19.getText():null);

            }

        }
        catch (RecognitionException re) {
            reportError(re);
            recover(input,re);
        }
        finally {
        }
        return text;
    }
    // $ANTLR end "push_CTID"

    // Delegated rules


 

    public static final BitSet FOLLOW_PROG_in_prog70 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_prolog_in_prog74 = new BitSet(new long[]{0x0000008000000000L});
    public static final BitSet FOLLOW_TL_BINDINGS_in_prog78 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_tl_bind_in_prog81 = new BitSet(new long[]{0x0000004000000008L});
    public static final BitSet FOLLOW_TERM_in_prog89 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_term_in_prog91 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_TL_BINDING_in_tl_bind122 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_push_ID_in_tl_bind124 = new BitSet(new long[]{0x0006200000000100L});
    public static final BitSet FOLLOW_type_in_tl_bind126 = new BitSet(new long[]{0x00001F0000140000L});
    public static final BitSet FOLLOW_term_in_tl_bind128 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_PROLOG_in_prolog169 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_datatype_in_prolog172 = new BitSet(new long[]{0x0008000000000008L});
    public static final BitSet FOLLOW_DATATYPE_in_datatype204 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_push_CTID_in_datatype209 = new BitSet(new long[]{0x0010000000000000L});
    public static final BitSet FOLLOW_args_in_datatype230 = new BitSet(new long[]{0x0020000000000000L});
    public static final BitSet FOLLOW_tconss_in_datatype250 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_TARGS_in_args284 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_push_TID_in_args289 = new BitSet(new long[]{0x0000000100000008L});
    public static final BitSet FOLLOW_TCONSTRUCTORS_in_tconss314 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_tcons_in_tconss318 = new BitSet(new long[]{0x0040000000000008L});
    public static final BitSet FOLLOW_TCONS_in_tcons337 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_push_CID_in_tcons339 = new BitSet(new long[]{0x0006200000000100L});
    public static final BitSet FOLLOW_type_in_tcons341 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_CASE_in_term365 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_type_in_term369 = new BitSet(new long[]{0x00001F0000140000L});
    public static final BitSet FOLLOW_term_in_term373 = new BitSet(new long[]{0x0000400000000000L});
    public static final BitSet FOLLOW_branches_in_term377 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_LETREC_in_term393 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_type_in_term395 = new BitSet(new long[]{0x0000000080000000L});
    public static final BitSet FOLLOW_push_ID_in_term397 = new BitSet(new long[]{0x00001F0000140000L});
    public static final BitSet FOLLOW_term_in_term401 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_TYPE_ABS_in_term427 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_push_TID_in_term429 = new BitSet(new long[]{0x00001F0000140000L});
    public static final BitSet FOLLOW_term_in_term433 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_TYPE_APP_in_term461 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_term_in_term465 = new BitSet(new long[]{0x0006200000000100L});
    public static final BitSet FOLLOW_type_in_term469 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_LAM_ABS_in_term493 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_push_ID_in_term495 = new BitSet(new long[]{0x0006200000000100L});
    public static final BitSet FOLLOW_type_in_term499 = new BitSet(new long[]{0x00001F0000140000L});
    public static final BitSet FOLLOW_term_in_term503 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_LAM_APP_in_term525 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_term_in_term529 = new BitSet(new long[]{0x00001F0000140000L});
    public static final BitSet FOLLOW_term_in_term533 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_VAR_in_term559 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_ID_in_term561 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_BRANCHES_in_branches609 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_branch_in_branches611 = new BitSet(new long[]{0x0000800000000008L});
    public static final BitSet FOLLOW_BRANCH_in_branch632 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_ID_in_branch634 = new BitSet(new long[]{0x00001F0000140000L});
    public static final BitSet FOLLOW_term_in_branch638 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_ARROW_in_type672 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_type_in_type676 = new BitSet(new long[]{0x0006200000000100L});
    public static final BitSet FOLLOW_type_in_type680 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_FOR_ALL_in_type704 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_push_TID_in_type706 = new BitSet(new long[]{0x0006200000000100L});
    public static final BitSet FOLLOW_type_in_type710 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_TVAR_in_type738 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_TID_in_type740 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_TVAR_in_type777 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_STARED_TYPE_in_type780 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_TID_in_type782 = new BitSet(new long[]{0x0000000000000008L});
    public static final BitSet FOLLOW_tcons_app_in_type806 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_TCONS_APP_in_tcons_app860 = new BitSet(new long[]{0x0000000000000004L});
    public static final BitSet FOLLOW_type_in_tcons_app864 = new BitSet(new long[]{0x0006200000000108L});
    public static final BitSet FOLLOW_type_in_tcons_app869 = new BitSet(new long[]{0x0006200000000108L});
    public static final BitSet FOLLOW_ID_in_push_ID924 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_ID_in_push_CID940 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_TID_in_push_TID956 = new BitSet(new long[]{0x0000000000000002L});
    public static final BitSet FOLLOW_TID_in_push_CTID971 = new BitSet(new long[]{0x0000000000000002L});

}